commonlibsse_ng\re\i/
InventoryEntryData.rs

1use core::ffi::CStr;
2use core::str;
3
4use crate::re::Actor::Actor;
5use crate::re::BSTList::BSSimpleList;
6use crate::re::EnchantmentItem::EnchantmentItem;
7use crate::re::ExtraCharge::ExtraCharge;
8use crate::re::ExtraDataList::ExtraDataList;
9use crate::re::ExtraEnchantment::ExtraEnchantment;
10use crate::re::GameSettingCollection::GameSettingCollection;
11use crate::re::Setting::SettingValue;
12use crate::re::TESBoundObject::TESBoundObject;
13use crate::re::TESBox::TESBox;
14use crate::re::TESEnchantableForm::TESEnchantableForm;
15use crate::re::TESForm::TESForm;
16use crate::re::{AlchemyItem, SoulLevel};
17
18#[derive(Debug, Clone)]
19pub struct InventoryEntryData {
20    pub object: *mut TESBoundObject,
21    pub extraLists: Option<TESBox<BSSimpleList<ExtraDataList>>>,
22    pub countDelta: i32,
23    pub pad14: u32,
24}
25const_assert_eq!(core::mem::size_of::<InventoryEntryData>(), 0x18);
26
27impl InventoryEntryData {
28    #[inline]
29    pub const fn new(object: *mut TESBoundObject, count_delta: i32) -> Self {
30        Self { object, extraLists: None, countDelta: count_delta, pad14: 0 }
31    }
32
33    #[inline]
34    pub fn add_extra_list(&mut self, extra: ExtraDataList) {
35        self.extraLists.get_or_insert_default().push_front(extra);
36    }
37
38    pub fn can_item_be_taken(
39        &self,
40        no_equipped: bool,
41        no_favorited: bool,
42        no_quest_item: bool,
43    ) -> bool {
44        let _ = no_equipped;
45        let _ = no_favorited;
46        let _ = no_quest_item;
47        todo!()
48    }
49
50    pub fn get_display_name(&mut self) -> Option<&CStr> {
51        let object = unsafe { self.object.as_ref() }?;
52        if let Some(extra_lists) = &mut self.extraLists {
53            for list in extra_lists.iter_mut() {
54                if let Some(name) = list.get_display_name(object) {
55                    return Some(name);
56                };
57            }
58        }
59        None
60    }
61
62    pub fn get_missing_display_name(&self) -> Option<&str> {
63        let game_settings = GameSettingCollection::get_singleton()?;
64        let ni_map = &game_settings.__base.settings.__base.__base.__base;
65        let missing_name = unsafe { ni_map.get(&c"sMissingName".as_ptr())?.as_ref() }?;
66        if let SettingValue::String(string) = missing_name.get_value() {
67            return str::from_utf8(string.to_bytes()).ok();
68        }
69
70        None
71    }
72
73    #[commonlibsse_ng_derive_internal::relocate_fn(se_id = 15788, ae_id = 16026)]
74    pub fn get_enchantment(&self) -> *mut EnchantmentItem {}
75
76    pub fn get_enchantment_charge(&self) -> Option<f64> {
77        let obj = self.get_object()?;
78        let enchantable_form =
79            unsafe { (obj as *const TESBoundObject).cast::<TESEnchantableForm>().as_ref()? };
80
81        let form_enchanting = !enchantable_form.formEnchanting.is_null();
82        let amount_of_enchantment = enchantable_form.amountOfEnchantment;
83
84        // First, if base form has enchantment and a non-zero amount, return 100.0
85        if form_enchanting && amount_of_enchantment != 0 {
86            return Some(100.0);
87        }
88
89        if let Some(extra_lists) = &self.extraLists {
90            for ex_list in extra_lists.iter() {
91                let x_charge = ex_list.get_by_type_as::<ExtraCharge>();
92                let x_enchant = ex_list.get_by_type_as::<ExtraEnchantment>();
93
94                match unsafe { (x_enchant.map(|e| e.as_ref()), x_charge.map(|c| c.as_ref())) } {
95                    // If ExtraEnchantment exists and has a valid enchantment and non-zero charge
96                    // AND ExtraCharge exists, compute the charge ratio
97                    (Some(x_enchant), Some(x_charge))
98                        if x_enchant.enchantment.is_some() && x_enchant.charge != 0 =>
99                    {
100                        return Some((x_charge.charge as f64 / x_enchant.charge as f64) * 100.0);
101                    }
102                    // If ExtraEnchantment exists (valid), but ExtraCharge is missing, fallback to 100%
103                    (Some(x_enchant), None)
104                        if x_enchant.enchantment.is_some() && x_enchant.charge != 0 =>
105                    {
106                        return Some(100.0);
107                    }
108                    // If only ExtraCharge exists, and base form is enchantable, compute using base enchantment amount
109                    (None, Some(x_charge)) if form_enchanting && amount_of_enchantment != 0 => {
110                        return Some(
111                            (x_charge.charge as f64 / amount_of_enchantment as f64) * 100.0,
112                        );
113                    }
114                    _ => {}
115                }
116            }
117        }
118
119        None
120    }
121
122    pub const fn get_object(&self) -> Option<&TESBoundObject> {
123        unsafe { self.object.as_ref() }
124    }
125
126    pub fn get_owner(&self) -> Option<&TESForm> {
127        todo!()
128    }
129
130    pub fn get_soul_level(&self) -> Option<SoulLevel> {
131        todo!()
132    }
133
134    pub fn get_value(&self) -> i32 {
135        todo!()
136    }
137
138    #[inline]
139    pub fn get_weight(&self) -> Option<f32> {
140        Some(unsafe { self.object.as_ref() }?.__base.__base.get_weight())
141    }
142
143    pub fn is_enchanted(&self) -> bool {
144        todo!()
145    }
146
147    pub fn is_favorited(&self) -> bool {
148        todo!()
149    }
150
151    pub fn is_leveled(&self) -> bool {
152        todo!()
153    }
154
155    pub fn is_poisoned(&self) -> bool {
156        todo!()
157    }
158
159    pub fn is_worn(&self) -> bool {
160        todo!()
161    }
162
163    #[commonlibsse_ng_derive_internal::relocate_fn(se_id = 15782, ae_id = 16020)]
164    pub fn is_owned_by(&self, test_owner: *mut Actor, default_to: bool) -> bool {}
165
166    pub fn is_quest_object(&self) -> bool {
167        todo!()
168    }
169
170    #[commonlibsse_ng_derive_internal::relocate_fn(se_id = 15786, ae_id = 16024)]
171    pub fn poison_object(&mut self, alchemy_item: *mut AlchemyItem, count: u32) {}
172}